﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SlimDX;
using SlimDX.Direct3D9;

namespace ThreeDI.UI.Abstraction
{
    public class FlexableCamera : TransformObject
    {
        #region [Members]
        float _XLimit = 0.7f;
        float _YLimit = 0.4f;
        float _xRotationAngle = 0;
        float _yRotationAngle = 0;
        float _xRotationAlpha = 1000;
        float _yRotationAlpha = 700;
        double _xAngleCount = 0;
        double _yAngleCount = 0;
        double _zPrevious;
        double _zNext;
        double _zCurrent;
        bool first = true;

        int _zCounter = 0;
        static int _normalizationFactor = 3;
        static int _editedNormFactor = _normalizationFactor;
        double _zMean = 0;
        #endregion
        private Application _application;
        public FlexableCamera(Application application)
            : base(application)
        {
            _application = application;
            _application.KeyDown+=new KeyEventHandler(_application_KeyDown);
        }


        private Device _device;
        public override void Load()
        {
            TransformationMatrix = Matrix.LookAtLH(
                new Vector3(0.0f, 0.0f, -20f),//eye
                new Vector3(0.0f, 0.0f, 0f),//target
                new Vector3(0.0f, 1.0f, 0.0f));//up 
            Rotation(0, 0, 0);
            Translation(0,0,-12);
        }

        public override void Render()
        {
            _application.Device.SetTransform(TransformState.View, TransformationMatrix);
            // _device.SetTransform(TransformState.View,TransformationMatrix);
            Matrix projectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4), 1.0f, 1.0f, 100.0f);
            // var projection = _device.SetTransform(TransformState.Projection, projectionMatrix);
            var projection = _application.Device.SetTransform(TransformState.Projection, projectionMatrix);
          
        }

        public void changePerspective(UserPoint point, float XAngle, float YAngle)
        {
            _xRotationAngle = XAngle / _xRotationAlpha;
            _yRotationAngle = YAngle / _yRotationAlpha;
            if (point.Z != 0)
            {
                _zMean += point.Z;
            }
            else
            {
                _editedNormFactor -= 1;
            }
            _zCounter++;

            if (first && point.Z != 0)
            {
                _zNext = _zPrevious = point.Z;
                first = false;
            }
            else
            {
                _zNext = point.Z;
            }

            if (XAngle > 0)
            {
                if (_xAngleCount >= _XLimit)
                {
                    _xAngleCount = _XLimit;
                    _xRotationAngle = 0;
                }
            }
            else if (XAngle < 0)
            {
                if (_xAngleCount <= -_XLimit)
                {
                    _xAngleCount = -_XLimit;
                    _xRotationAngle = 0;
                }
            }

            if (YAngle > 0)
            {
                if (_yAngleCount >= _YLimit)
                {
                    _yAngleCount = _YLimit;
                    _yRotationAngle = 0;
                }
            }
            else if (YAngle < 0)
            {
                if (_yAngleCount <= -(_YLimit))
                {
                    _yAngleCount = -_YLimit;
                    _yRotationAngle = 0;
                }
            }

            if (XAngle > 7f || XAngle < -7f)
            {
                Rotation(_xRotationAngle, 0, 0);
                _xAngleCount += _xRotationAngle;
            }

            if (YAngle > 7f || YAngle < -12f)
            {
                //Rotation(0, _yRotationAngle, 0);
                _yAngleCount += _yRotationAngle;
            }

            if (_zCounter % _normalizationFactor == 0)
            {
                if (_zMean > 0)
                {
                    _zMean /= _editedNormFactor;
                    _zCurrent = _zMean - _zPrevious;
                }

                if (_zCurrent > 0)
                {
                    //Translation(0, 0, 1f);
                }
                else if (_zCurrent < 0)
                {
                    //Translation(0, 0, -1f);
                }
                _zPrevious = _zMean;
                _zMean = 0;
            }

            //_zCurrent = _zNext - _zPrevious;

            //Translation(0, 0, 1f);

            //_zPrevious = _zNext;
        }

        public void _application_KeyDown(object sender, KeyEventArgs e)
        {
            
            //     Handle left,right,Up,Down keys 
            if ((e.KeyCode == Keys.Left))
            {
                Rotation(-0.1f, 0, 0);
               // Translation(0, 0, 0);
            }
            if ((e.KeyCode == Keys.Right))
            {
                Rotation(0.1f, 0, 0);
                //Translation(1, 0, 0);
            }
            if ((e.KeyCode == Keys.Up))
            {
               // Rotation(0, 0, 1);
                Translation(0, 0, -0.1f);
            }
            if ((e.KeyCode == Keys.Down))
            {
                //Rotation(0, 0, -1);
                Translation(0, 0,0.1f);
            }
            if ((e.KeyCode == Keys.W))
            {
                //Rotation(0, 0, -1);
                Translation(0, -0.1f, 0);
            }
            if ((e.KeyCode == Keys.S))
            {
                //Rotation(0, 0, -1);
                Translation(0, 0.1f, 0);
            }
        }
    }
}


